package com.hector.meinewerk.common;

import java.util.ArrayList;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Rect;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.Window;
import android.widget.LinearLayout;
import android.widget.ProgressBar;

import com.commonsware.cwac.cache.HashMapManager;
import com.commonsware.cwac.cache.SimpleWebImageCache;
import com.commonsware.cwac.thumbnail.ThumbnailBus;
import com.commonsware.cwac.thumbnail.ThumbnailMessage;
import com.hector.meinewerk.client.R;
import com.hector.meinewerk.constants.IntentConstants;
import com.hector.meinewerk.dto.UserDTO;
import com.hector.meinewerk.lib.network.http.HTTPClient;
import com.hector.meinewerk.lib.network.http.HTTPRequest;
import com.hector.meinewerk.listener.OnDialogControlListener;
import com.hector.meinewerk.utils.GlobalUtils;
import com.hector.meinewerk.utils.MyLog;
import com.hector.meinewerk.utils.StringUtil;
import com.hector.meinewerk.utils.ui.SnapAnimation;

/**
 * 
 * base activity of application
 * 
 * @author: HaiTC3
 * @version: 1.1
 * @since: 1.0 | Mar 6, 2013
 */
public abstract class BaseActivity extends Activity implements
		DialogInterface.OnCancelListener, OnCompositeControlListener,
		OnDialogControlListener {
	public Activity mActivity;
	public Context mContext;
	
	// chuoi action cua cac broadcast message
	public static final String BASE_ACTION = "hai.com.project.action";
	protected final int ICON_RIGHT_PARENT = 0;
	protected final int ICON_NEXT_1 = 1;
	protected final int ICON_BUTTON = -1;

	// broadcast receiver, nhan broadcast
	public BroadcastReceiver receiver = new BroadcastReceiver() {
		@Override
		public void onReceive(Context context, Intent intent) {
			int action = intent.getExtras().getInt("project.action");
			int hasCode = intent.getExtras().getInt("project.hashCode");
			if (hasCode != BaseActivity.this.hashCode()) {
				receiveBroadcast(action, intent.getExtras());
			}
		}
	};

	// dialog hien thi khi request
	private static ProgressDialog progressDlg;
	// progressBar tren header
	private ProgressBar pbHeaderLoading;

	// kiem tra activity da finish hay chua
	public boolean isFinished = false;
	// co nhan broadcast hay khong
	boolean broadcast;

	public ActionEvent actionEventBeforReLogin = null; // save actionevent
	// mang cac request dang xu ly do activity request
	private ArrayList<HTTPRequest> unblockReqs = new ArrayList<HTTPRequest>();
	private ArrayList<HTTPRequest> blockReqs = new ArrayList<HTTPRequest>();
	// activity co dang active
	private boolean isActive;
	SnapAnimation noticeInAppAnimation;

	public static SimpleWebImageCache thumnail;

	private LinearLayout rootView;
	protected LinearLayout mainContent;
	View rlHeader;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		mContext = getApplicationContext();
		mActivity = this;
		
		GlobalInfo.getInstance().setAppContext(getApplicationContext());
		GlobalInfo.getInstance().setActivityContext(this);
		if (savedInstanceState != null) {
			if (savedInstanceState
					.containsKey(IntentConstants.INTENT_GLOBAL_BUNDLE)) {
				getIntent()
						.putExtras(
								savedInstanceState
										.getBundle(IntentConstants.INTENT_GLOBAL_BUNDLE));
			}
			if (StringUtil.isNullOrEmpty(HTTPClient.sessionID)
					&& savedInstanceState
							.containsKey(IntentConstants.INTENT_SESSION_ID)) {
				HTTPClient.sessionID = savedInstanceState
						.getString(IntentConstants.INTENT_SESSION_ID);
			}
		}

		this.requestWindowFeature(Window.FEATURE_NO_TITLE);
		requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
		try {
			IntentFilter filter = new IntentFilter(BaseActivity.BASE_ACTION);
			registerReceiver(receiver, filter);
			this.broadcast = true;
		} catch (Exception e) {
		}

	}

	/**
	 * 
	 * ham onCreate voi tham so co dang ky lang nghe broadcast khong
	 * 
	 * @param @param savedInstanceState
	 * @param @param broadcast
	 * @return: void
	 * @author: HaiTC3
	 * @date: Mar 6, 2013
	 */
	protected void onCreate(Bundle savedInstanceState, boolean broadcast) {
		super.onCreate(savedInstanceState);
		GlobalInfo.getInstance().setAppContext(getApplicationContext());
		GlobalInfo.getInstance().setActivityContext(this);
		if (savedInstanceState != null) {
			if (savedInstanceState
					.containsKey(IntentConstants.INTENT_GLOBAL_BUNDLE)) {
				getIntent()
						.putExtras(
								savedInstanceState
										.getBundle(IntentConstants.INTENT_GLOBAL_BUNDLE));
			}
			if (StringUtil.isNullOrEmpty(HTTPClient.sessionID)
					&& savedInstanceState
							.containsKey(IntentConstants.INTENT_SESSION_ID)) {
				HTTPClient.sessionID = savedInstanceState
						.getString(IntentConstants.INTENT_SESSION_ID);
			}
		}

		this.requestWindowFeature(Window.FEATURE_NO_TITLE);
		requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
		this.broadcast = broadcast;
		if (broadcast) {
			try {
				IntentFilter filter = new IntentFilter(BaseActivity.BASE_ACTION);
				registerReceiver(receiver, filter);
			} catch (Exception e) {
			}
		}

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see android.app.Activity#onSaveInstanceState(android.os.Bundle)
	 */
	@Override
	protected void onSaveInstanceState(Bundle outState) {
		// TODO Auto-generated method stub
		if (getIntent().getExtras() != null) {
			outState.putBundle(IntentConstants.INTENT_GLOBAL_BUNDLE,
					getIntent().getExtras());
		}
		if (!StringUtil.isNullOrEmpty(HTTPClient.sessionID)) {
			outState.putString(IntentConstants.INTENT_SESSION_ID,
					HTTPClient.sessionID);
		}
		super.onSaveInstanceState(outState);
	}

	@Override
	public void finish() {
		isFinished = true;
		super.finish();
	}

	@Override
	public void finishActivity(int requestCode) {
		isFinished = true;
		super.finishActivity(requestCode);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see android.app.Activity#onLowMemory()
	 */
	@Override
	public void onLowMemory() {
		HashMapManager.getInstance().clearAllHashMapExcept(this.toString());
		super.onLowMemory();
	}

	@Override
	protected void onDestroy() {
		// TODO Auto-generated method stub
		if (this == GlobalInfo.getInstance().lastShowActivity) {
			GlobalInfo.getInstance().lastShowActivity = null;
		}
		removeAllProcessingRequest();
		try {
			unregisterReceiver(receiver);
		} catch (Exception e) {
		}
		GlobalUtils.nullViewDrawablesRecursive(rootView);
		HashMapManager.getInstance().clearHashMapById(this.toString());
		System.gc();
		System.runFinalization();

		super.onDestroy();

	}

	/**
	 * 
	 * init activity
	 * 
	 * @param
	 * @return: void
	 * @author: HaiTC3
	 * @date: Mar 6, 2013
	 */
	private void initialize() {
		LinearLayout rootView = (LinearLayout) findViewById(R.id.ll_app_main);
		LayoutInflater inflater = (LayoutInflater) this
				.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
		rlHeader = inflater.inflate(R.layout.app_header, null);
		rootView.addView(rlHeader, 0);

		// Cap nhat hien thi logo loading
		pbHeaderLoading = (ProgressBar) rlHeader.findViewById(R.id.pb_app);
	}

	@Override
	public void setContentView(int layoutResID) {
		super.setContentView(R.layout.layout_app);
		rootView = (LinearLayout) findViewById(R.id.ll_app_main);
		mainContent = (LinearLayout) findViewById(R.id.ll_content);
		LayoutInflater inflater = (LayoutInflater) this
				.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
		inflater.inflate(layoutResID, mainContent);

		initialize();
	}

	@Override
	public void setContentView(View view) {
		// TODO Auto-generated method stub
		super.setContentView(R.layout.layout_app);
		rootView = (LinearLayout) findViewById(R.id.ll_app_main);
		mainContent = (LinearLayout) findViewById(R.id.ll_content);
		mainContent.addView(view);
		initialize();
	}

	/**
	 * 
	 * remove view
	 * 
	 * @param @param view
	 * @return: void
	 * @author: HaiTC3
	 * @date: Mar 6, 2013
	 */
	public void removeView(View view) {
		mainContent.removeView(view);
	}

	@Override
	protected void onResume() {
		super.onResume();
		isActive = true;
		GlobalInfo.getInstance().setAppActive(true);
		GlobalInfo.getInstance().lastShowActivity = this;
	}

	@Override
	protected void onPause() {
		super.onPause();
		isActive = false;
		GlobalInfo.getInstance().setAppActive(false);
		System.gc();
	}

	/**
	 * 
	 * set logo header
	 * 
	 * @param @param visible
	 * @return: void
	 * @author: HaiTC3
	 * @date: Mar 6, 2013
	 */
	public void setLogoVisible(int visible) {
		rlHeader.setVisibility(visible);
	}

	/**
	 * 
	 * get logo header
	 * 
	 * @param @return
	 * @return: View
	 * @author: HaiTC3
	 * @date: Mar 6, 2013
	 */
	public View getLogoHeader() {
		return rlHeader;
	}

	public void setLogoLoading(boolean visible) {
		if (pbHeaderLoading != null) {
			if (visible) {
				pbHeaderLoading.setVisibility(View.VISIBLE);
			} else {
				pbHeaderLoading.setVisibility(View.GONE);
			}
		}
	}

	/**
	 * xu ly keyboard
	 */
	public void onSoftKeyboardShown(boolean isShow) {
	}

	/**
	 * 
	 * show dialog
	 * 
	 * @param @param mes
	 * @param @return
	 * @return: AlertDialog
	 * @author: HaiTC3
	 * @date: Mar 6, 2013
	 */
	public AlertDialog showDialog(final String mes) {
		AlertDialog alertDialog = null;
		try {
			alertDialog = new AlertDialog.Builder(this).create();
			alertDialog.setMessage(mes);
			alertDialog.setButton("Close",
					new DialogInterface.OnClickListener() {
						public void onClick(DialogInterface dialog, int which) {
							dialog.dismiss();
							return;
						}
					});
			alertDialog.show();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return alertDialog;
	}

	/**
	 * 
	 * Show dialog voi msg thong bao, khi click ok thi dong va finsih activity
	 * 
	 * @param @param mes
	 * @param @param isFinish
	 * @param @return
	 * @return: AlertDialog
	 * @author: HaiTC3
	 * @date: Mar 6, 2013
	 */
	public AlertDialog showDialogWithFinsihActivity(final String mes,
			boolean isFinish) {
		AlertDialog alertDialog = null;
		try {
			alertDialog = new AlertDialog.Builder(this).create();
			alertDialog.setMessage(mes);
			alertDialog.setButton("Close",
					new DialogInterface.OnClickListener() {
						public void onClick(DialogInterface dialog, int which) {
							dialog.dismiss();
							finish();
							return;

						}
					});
			alertDialog.show();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return alertDialog;
	}

	/**
	 * 
	 * handle event from model
	 * 
	 * @param @param modelEvent
	 * @return: void
	 * @author: HaiTC3
	 * @date: Mar 6, 2013
	 */
	public void handleModelViewEvent(ModelEvent modelEvent) {
		ActionEvent e = modelEvent.getActionEvent();
		switch (e.action) {
		case ActionEventConstant.LOG_OUT:
			// sentBroadcast(ActionEventConstant.ACTIVITY_FINISH, new Bundle());
			break;
		case ActionEventConstant.LOG_OUT_EXIT:
			// sentBroadcast(ActionEventConstant.ACTIVITY_FINISH, new Bundle());
			// finish();
			break;
		}

	}

	/**
	 * 
	 * lay cache chung cho tat ca man hinh lien quan toi avatar cua dia diem
	 * 
	 * @param @return
	 * @return: SimpleWebImageCache<ThumbnailBus,ThumbnailMessage>
	 * @author: HaiTC3
	 * @date: Mar 6, 2013
	 */
	public static SimpleWebImageCache<ThumbnailBus, ThumbnailMessage> getCacheAvatarLocation() {
		if (thumnail == null) {
			ThumbnailBus bus = new ThumbnailBus();
			thumnail = new SimpleWebImageCache<ThumbnailBus, ThumbnailMessage>(
					null, null, 101, bus);
		}
		return thumnail;
	}

	/**
	 * 
	 * handle error event from model
	 * 
	 * @param @param modelEvent
	 * @return: void
	 * @author: HaiTC3
	 * @date: Mar 6, 2013
	 */
	public void handleErrorModelViewEvent(ModelEvent modelEvent) {
		switch (modelEvent.getModelCode()) {
		case ErrorConstants.ERROR_COMMON:
			closeProgressDialog();
			showDialog(StringUtil.getString(R.string.ERROR_COMMON));
			break;
		case ErrorConstants.ERROR_NO_CONNECTION:
			showDialog(modelEvent.getModelMessage());
			break;
		case ErrorConstants.ERROR_OBJECT_NOT_EXISTS:
			showDialog(StringUtil.getString(R.string.ERROR_OBJECT_NOT_EXISTED));
			break;

		case ErrorConstants.ERROR_SESSION_RESET: // error when session time out.
			// re-login and re-request
			actionEventBeforReLogin = modelEvent.getActionEvent();
			if (actionEventBeforReLogin != null
					&& !actionEventBeforReLogin.isRelogin) {
				actionEventBeforReLogin.isRelogin = true;

//				if (OAuthRequestManager.getInstance().reInit()) {
//					actionEventBeforReLogin.controller
//							.handleViewEvent(actionEventBeforReLogin);
//				} else {// get Oauth fail
//					sentBroadcast(ActionEventConstant.HANDLE_RELOGIN_ERROR,
//							new Bundle());
//				}

			} else {
				AlertDialog alertDialogError = new AlertDialog.Builder(this)
						.create();
				alertDialogError.setMessage(StringUtil
						.getString(R.string.TEXT_RE_LOGIN_ERROR));
				alertDialogError.setButton(StringUtil.getString(R.string.OK),
						new DialogInterface.OnClickListener() {
							public void onClick(DialogInterface dialog,
									int which) {
								dialog.dismiss();
								sentBroadcast(
										ActionEventConstant.HANDLE_RELOGIN_ERROR,
										new Bundle());
								finish();
							}
						});
				alertDialogError.show();
			}
			break;
		case ErrorConstants.ERROR_ACCOUNT_LOCKED_REQUEST:
			Bundle bd = new Bundle();
			UserDTO userDTO = new UserDTO();
			userDTO.strUserName = GlobalInfo.getInstance().getProfile()
					.getUserData().strUserName;
			bd.putSerializable("data", userDTO);
			// sentBroadcast(ActionEventConstant.XMPP_LOCK_ACCOUNT, bd);
			break;
		default:
			closeProgressDialog();
			if (!StringUtil.isNullOrEmpty(modelEvent.getModelMessage())) {
				showDialog(modelEvent.getModelMessage());
			}
			break;
		}
	}

	/**
	 * 
	 * show progress dialog
	 * 
	 * @param @param content
	 * @return: void
	 * @author: HaiTC3
	 * @date: Mar 6, 2013
	 */
	public void showProgressDialog(String content) {
		showProgressDialog(content, true);
	}

	/**
	 * 
	 * show progress dialog with flag can cancel
	 * 
	 * @param @param content
	 * @param @param cancleable
	 * @return: void
	 * @author: HaiTC3
	 * @date: Mar 6, 2013
	 */
	public void showProgressDialog(String content, boolean cancleable) {
		if (progressDlg != null && progressDlg.isShowing()) {
			closeProgressDialog();
		}
		progressDlg = ProgressDialog.show(this, "", content, true, true);
		progressDlg.setCancelable(cancleable);
		progressDlg.setCanceledOnTouchOutside(false);
		progressDlg.setOnCancelListener(this);
	}

	/**
	 * 
	 * close progress dialog
	 * 
	 * @param
	 * @return: void
	 * @author: HaiTC3
	 * @date: Mar 6, 2013
	 */
	public void closeProgressDialog() {
		if (progressDlg != null) {
			try {
				progressDlg.dismiss();
				progressDlg = null;
			} catch (Exception e) {
				MyLog.i("Exception", e.toString());
			}
		}
	}

	/**
	 * 
	 * show progress dialog percent
	 * 
	 * @param @param content
	 * @return: void
	 * @author: HaiTC3
	 * @date: Mar 6, 2013
	 */
	public void showProgressPercentDialog(String content) {
		progressDlg = new ProgressDialog(this);
		progressDlg.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
		progressDlg.setMessage(content);
		progressDlg.setCancelable(false);
		progressDlg.show();
	}

	/**
	 * 
	 * update progress percent dialog
	 * 
	 * @param @param percent
	 * @return: void
	 * @author: HaiTC3
	 * @date: Mar 6, 2013
	 */
	public void updateProgressPercentDialog(int percent) {
		if (progressDlg != null) {
			progressDlg.setProgress(percent);
		}
	}

	/**
	 * 
	 * close progress percent dialog
	 * 
	 * @param
	 * @return: void
	 * @author: HaiTC3
	 * @date: Mar 6, 2013
	 */
	public void closeProgressPercentDialog() {
		if (progressDlg != null) {
			progressDlg.dismiss();
			progressDlg = null;
		}
	}

	/**
	 * 
	 * receive broad cast
	 * 
	 * @param @param action
	 * @param @param bundle
	 * @return: void
	 * @author: HaiTC3
	 * @date: Mar 6, 2013
	 */
	public void receiveBroadcast(int action, Bundle bundle) {
		try {
			Profile profile = GlobalInfo.getInstance().getProfile();
			if (profile.getUserData() == null) {
				return;
			}
			switch (action) {
			default:
				break;
			}
		} catch (Exception e) {
			MyLog.i(this.getClass().getName() + " - receiveBroadcast",
					e.getMessage() + "/" + e.toString());
		}
	}

	public void sentBroadcast(int action, Bundle bundle) {
		Intent intent = new Intent(BASE_ACTION);
		bundle.putInt("project.action", action);
		bundle.putInt("project.hashCode", intent.getClass().hashCode());
		intent.putExtras(bundle);
		sendBroadcast(intent);
	}

	/**
	 * 
	 * get status bar height
	 * 
	 * @param @return
	 * @return: int
	 * @author: HaiTC3
	 * @date: Mar 6, 2013
	 */
	public int getStatusBarHeight() {
		Rect r = new Rect();
		Window w = getWindow();
		w.getDecorView().getWindowVisibleDisplayFrame(r);
		return r.top;
	}

	/**
	 * 
	 * get title bar height
	 * 
	 * @param @return
	 * @return: int
	 * @author: HaiTC3
	 * @date: Mar 6, 2013
	 */
	public int getTitleBarHeight() {
		int viewTop = getWindow().findViewById(Window.ID_ANDROID_CONTENT)
				.getTop();
		return (viewTop - getStatusBarHeight());
	}

	/**
	 * 
	 * get flag active
	 * 
	 * @param @return
	 * @return: boolean
	 * @author: HaiTC3
	 * @date: Mar 6, 2013
	 */
	public boolean isActive() {
		return isActive;
	}

	/**
	 * 
	 * add processing request
	 * 
	 * @param @param req
	 * @param @param isBlock
	 * @return: void
	 * @author: HaiTC3
	 * @date: Mar 6, 2013
	 */
	public void addProcessingRequest(HTTPRequest req, boolean isBlock) {
		if (isBlock) {
			blockReqs.add(req);
		} else {
			unblockReqs.add(req);
		}
	}

	/**
	 * 
	 * remove all processing request
	 * 
	 * @param
	 * @return: void
	 * @author: HaiTC3
	 * @date: Mar 6, 2013
	 */
	public void removeAllProcessingRequest() {
		cancelRequest(blockReqs);
		cancelRequest(unblockReqs);
	}

	/**
	 * 
	 * remove processing request
	 * 
	 * @param @param req
	 * @param @param isBlock
	 * @return: void
	 * @author: HaiTC3
	 * @date: Mar 6, 2013
	 */
	public void removeProcessingRequest(HTTPRequest req, boolean isBlock) {
		if (isBlock) {
			cancelRequest(blockReqs, req);
		} else {
			cancelRequest(unblockReqs, req);
		}
	}

	/**
	 * 
	 * cancel request
	 * 
	 * @param @param arrReq
	 * @return: void
	 * @author: HaiTC3
	 * @date: Mar 6, 2013
	 */
	private void cancelRequest(ArrayList<HTTPRequest> arrReq) {
		HTTPRequest req = null;
		for (int i = 0, n = arrReq.size(); i < n; i++) {
			req = arrReq.get(i);
			req.setAlive(false);
		}
		arrReq.clear();
	}

	/**
	 * 
	 * cancel request
	 * 
	 * @param @param arrReq
	 * @param @param req
	 * @return: void
	 * @author: HaiTC3
	 * @date: Mar 6, 2013
	 */
	private void cancelRequest(ArrayList<HTTPRequest> arrReq, HTTPRequest req) {
		HTTPRequest curReq = null;
		for (int i = 0, n = arrReq.size(); i < n; i++) {
			curReq = arrReq.get(i);
			if (curReq == req) {
				arrReq.remove(i);
				req.setAlive(false);
				break;
			}
		}
		arrReq.clear();
	}

	/**
	 * 
	 * Kiem tra co ton tai request dang xu ly hay khong
	 * 
	 * @param @param reqAction
	 * @param @return
	 * @return: boolean
	 * @author: HaiTC3
	 * @date: Mar 6, 2013
	 */
	public boolean checkExistRequestProcessing(int reqAction) {
		boolean res = false;
		HTTPRequest curReq = null;
		for (int i = 0, n = blockReqs.size(); i < n; i++) {
			curReq = blockReqs.get(i);
			if (curReq.isAlive() && curReq.getAction() == reqAction) {
				res = true;
				break;
			}
		}
		return res;
	}

	@Override
	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * android.content.DialogInterface.OnCancelListener#onCancel(android.content
	 * .DialogInterface)
	 */
	public void onCancel(DialogInterface dialog) {
		// dang hien thi progressDialog => bam nut back
		// TODO Auto-generated method stub
		if (dialog == progressDlg) {
			cancelRequest(this.blockReqs);
		}
	}

	/**
	 * 
	 * Kiem tra progress dialog dang show
	 * 
	 * @param @return
	 * @return: boolean
	 * @author: HaiTC3
	 * @date: Mar 6, 2013
	 */
	public boolean isProgressDialogShowing() {
		boolean result = false;
		if (progressDlg != null) {
			result = progressDlg.isShowing();
		}
		return result;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.hai.common.OnCompositeControlListener#onEvent(int,
	 * android.view.View, java.lang.Object)
	 */
	@Override
	public void onEvent(int eventType, View control, Object data) {
		// TODO Auto-generated method stub
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.hai.view.OnDialogControlListener#onDialogListener(int,
	 * int, java.lang.Object)
	 */
	@Override
	public void onDialogListener(int eventType, int eventCode, Object data) {
		// TODO Auto-generated method stub

	}

	/**
	 * 
	 * get header height
	 * 
	 * @param @return
	 * @return: int
	 * @author: HaiTC3
	 * @date: Mar 6, 2013
	 */
	public int getHeaderHeight() {
		return rlHeader.getMeasuredHeight();
	}

}
